/*

 */
package com.ohos.connent.modelcloud.biz.modular.pro.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ohos.connent.modelcloud.biz.modular.pro.entity.BizProCategory;
import com.ohos.connent.modelcloud.biz.modular.pro.entity.BizProfile;
import com.ohos.connent.modelcloud.biz.modular.pro.mapper.BizProfileMapper;
import com.ohos.connent.modelcloud.biz.modular.pro.param.*;
import com.ohos.connent.modelcloud.biz.modular.pro.result.BizProfileDetailResult;
import com.ohos.connent.modelcloud.biz.modular.pro.result.BizProfileUploadAuthResult;
import com.ohos.connent.modelcloud.biz.modular.pro.service.BizProCategoryService;
import com.ohos.connent.modelcloud.biz.modular.pro.service.BizProfileService;
import com.ohos.connent.modelcloud.common.cache.CommonCacheOperator;
import com.ohos.connent.modelcloud.common.enums.CommonSortOrderEnum;
import com.ohos.connent.modelcloud.common.exception.CommonException;
import com.ohos.connent.modelcloud.common.page.CommonPageRequest;
import com.ohos.connent.modelcloud.dev.api.DevFileApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * Profile-Service接口实现类
 **/
@Slf4j
@Service
public class BizProfileServiceImpl extends ServiceImpl<BizProfileMapper, BizProfile> implements BizProfileService {

    private static final String DEV_FILE_HWYUN_AUTH_URL_CACHE_KEY = "dev-file:MODEL_HUAWEI_YUN_AUTH_URL:";

    @Resource
    DevFileApi devFileApi;

    @Resource
    CommonCacheOperator commonCacheOperator;

    @Resource
    private BizProCategoryService bizProCategoryService;

    @Override
    public Page<BizProfile> page(BizProfilePageParam bizProfilePageParam) {
        QueryWrapper<BizProfile> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(BizProfile::getId, BizProfile::getFileId, BizProfile::getName, BizProfile::getDescription, BizProfile::getCreateTime);
        if (ObjectUtil.isNotEmpty(bizProfilePageParam.getSearchKey())) {
            queryWrapper.lambda().and(p -> p.like(BizProfile::getName, bizProfilePageParam.getSearchKey()));
        }
        if (ObjectUtil.isAllNotEmpty(bizProfilePageParam.getSortField(), bizProfilePageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizProfilePageParam.getSortOrder());

            queryWrapper.orderBy(true, bizProfilePageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizProfilePageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizProfile::getCreateTime);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public List<BizProfile> list(BizProfileListParam bizProfileListParam) {
        QueryWrapper<BizProfile> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(BizProfile::getId, BizProfile::getFileId, BizProfile::getName, BizProfile::getCreateTime);
        if (ObjectUtil.isNotEmpty(bizProfileListParam.getSearchKey())) {
            queryWrapper.lambda().and(p -> p.like(BizProfile::getFileId, bizProfileListParam.getSearchKey())
                    .or().like(BizProfile::getName, bizProfileListParam.getSearchKey()));
        }
        return this.list(queryWrapper.lambda().orderByDesc(BizProfile::getCreateTime));
    }

    @Override
    public BizProfileUploadAuthResult getHWYunUploadAuthUrlAndFileId(BizProfileUploadParam bizProfileUploadParam) {
        String fileId = devFileApi.getFileUploadReturnIdHUAWEI(bizProfileUploadParam.getFileName(), bizProfileUploadParam.getTimeoutSeconds());
        String url = (String) commonCacheOperator.get(DEV_FILE_HWYUN_AUTH_URL_CACHE_KEY + fileId);
        if (ObjectUtil.isEmpty(url)) {
            throw new CommonException("文件路径不存在或已过期");
        }

        return new BizProfileUploadAuthResult().setFileId(fileId).setUrl(url);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(BizProfileAddParam bizProfileAddParam) {
        checkAddParam(bizProfileAddParam);
        String id = IdWorker.getIdStr();
        BizProfile bizProfile = BeanUtil.toBean(bizProfileAddParam, BizProfile.class).setId(id);
        this.save(bizProfile);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(BizProfileIdsParam bizProfileIdsParam) {
        List<BizProfile> bizProfiles = this.listByIds(bizProfileIdsParam.getIds());
        if (CollectionUtils.isEmpty(bizProfiles)) {
            throw new CommonException("文件已删除，请勿重复执行");
        }
        // 判断是否被品类使用
        if (bizProCategoryService.count(Wrappers.lambdaQuery(BizProCategory.class).in(BizProCategory::getFileId,
                bizProfiles.stream().map(BizProfile::getFileId).collect(Collectors.toList()))) > 0) {
            throw new CommonException("存在profile已被品类使用，无法删除");
        }
        this.removeByIds(bizProfileIdsParam.getIds());
    }

    @Override
    public String getFileDownloadAuthUrlHUAWEI(BizProfileFileIdParam bizProfileFileIdParam) {
        String url = devFileApi.getFileDownloadAuthUrlHUAWEI(bizProfileFileIdParam.getFileId(), 3600L);
        if (ObjectUtil.isEmpty(url) || "没有相关文件".equals(url)) {
            throw new CommonException("无法获取文件下载路径");
        }

        return url;
    }

    @Override
    public BizProfile queryEntity(String id) {
        BizProfile bizProfile =  this.getById(id);
        if (ObjectUtil.isEmpty(bizProfile)) {
            throw new CommonException("profile不存在，id值为：{}", id);
        }
        return bizProfile;
    }

    @Override
    public void upload(MultipartFile file, String fileId) {
        devFileApi.storageFileHUAWEI(fileId, file);

        if (!devFileApi.isExistingFileHUAWEI(fileId)) {
            throw new CommonException("文件上传失败，请重传文件");
        }
    }

    @Override
    public BizProfileDetailResult detail(String id) {
        BizProfile bizProfile = this.queryEntity(id);
        BizProfileDetailResult bizProfileDetailResult = BeanUtil.toBean(bizProfile, BizProfileDetailResult.class);
        bizProfileDetailResult.setFileName(devFileApi.getFileName(bizProfileDetailResult.getFileId()));
        return bizProfileDetailResult;
    }

    @Override
    public void edit(BizProfileEditParam bizProfileEditParam) {
        String fileId = bizProfileEditParam.getFileId();
        if (!devFileApi.isExistingFileHUAWEI(fileId)) {
            throw new CommonException("文件上传失败，请重传文件");
        }
        List<BizProfile> list = this.list(new QueryWrapper<BizProfile>().lambda()
                .eq(BizProfile::getName, bizProfileEditParam.getName()));
        if (!list.isEmpty() && !list.get(0).getId().equals(bizProfileEditParam.getId())) {
            throw new CommonException("存在重复的名称：{}", bizProfileEditParam.getName());
        }
        BizProfile bizProfile = BeanUtil.toBean(bizProfileEditParam, BizProfile.class);
        this.updateById(bizProfile);
    }

    private void checkAddParam(BizProfileAddParam bizProfileAddParam) {
        String fileId = bizProfileAddParam.getFileId();
        if (!devFileApi.isExistingFileHUAWEI(fileId)) {
            throw new CommonException("文件上传失败，请重传文件");
        }

        boolean hasSameName = this.count(new QueryWrapper<BizProfile>().lambda()
                .eq(BizProfile::getName, bizProfileAddParam.getName())) > 0;
        if (hasSameName) {
            throw new CommonException("存在重复的名称：{}", bizProfileAddParam.getName());
        }
    }
}
